#pragma once

#include "../util/except.hh"
#include "../poco/vocabulary.hh"
#include "../poco/word.hh"
#include "../repository/vocabulary-repository.hh"

namespace WordMemory
{
    class VocabularyService
    {
    public:
        static VocabularyService &instance()
        {
            static VocabularyService inst;
            return inst;
        }

        std::vector<Vocabulary> getVocabularies(int user_id)
        {
            return VocabularyRepository::instance().getVocabularies(user_id);
        }

        Vocabulary addVocabulary(int user_id, const std::string &name)
        {
            if (name.empty())
                throw ServerExcept("Vocabulary name cannot be empty");

            if (name.find("收藏") != std::string::npos
             || name.find("错题") != std::string::npos) {
                throw ServiceExcept("Cannot create vocabulary with reserved name.");
            }

            return VocabularyRepository::instance().addVocabulary(user_id, name);
        }

        std::vector<Word> getWordsOnlyTextByVocabularyId(int vocabulary_id)
        {
            return VocabularyRepository::instance().getWordsOnlyTextByVocabularyId(vocabulary_id);
        }

        // 添加单词到用户收藏夹
        void addWordToFavorites(int user_id, int word_id)
        {
            // 获取或创建用户的收藏词库
            Vocabulary fav_vocab = VocabularyRepository::instance().getOrCreateFavoritesVocabulary(user_id);
            if (fav_vocab.id == 0) {
                throw ServiceExcept("Could not get or create favorites vocabulary for user.");
            }

            // 将单词添加到收藏词库
            VocabularyRepository::instance().addWordToVocabulary(fav_vocab.id, word_id);
        }

        // 从用户收藏夹移除单词
        void removeWordFromFavorites(int user_id, int word_id)
        {
            Vocabulary favorites_vocab = VocabularyRepository::instance().getOrCreateFavoritesVocabulary(user_id);
             if (favorites_vocab.id == 0) {
                throw ServiceExcept("Could not get favorites vocabulary for user. Cannot remove word.");
            }
            VocabularyRepository::instance().removeWordFromVocabulary(favorites_vocab.id, word_id);
        }

        void addWordToMistakesBook(int user_id, int word_id)
        {
            Vocabulary mistakes_book = VocabularyRepository::instance().getOrCreateMistakesBook(user_id);
            if (mistakes_book.id == 0) {
                throw ServiceExcept("Could not get or create mistakes book.");
            }
            VocabularyRepository::instance().addWordToVocabulary(mistakes_book.id, word_id);
            spdlog::info("Service: Added word_id {} to mistakes book for user_id {}", word_id, user_id);
        }

        void removeWordFromMistakesBook(int user_id, int word_id)
        {
            Vocabulary mistakes_book = VocabularyRepository::instance().getOrCreateMistakesBook(user_id);
             if (mistakes_book.id == 0) {
                throw ServiceExcept("Mistakes book not found, cannot remove word.");
            }
            VocabularyRepository::instance().removeWordFromVocabulary(mistakes_book.id, word_id);
            spdlog::info("Service: Removed word_id {} from mistakes book for user_id {}", word_id, user_id);
        }

        std::vector<Word> getMistakesBookWords(int user_id)
        {
            Vocabulary mistakes_book = VocabularyRepository::instance().getOrCreateMistakesBook(user_id);
            if (mistakes_book.id == 0) {
                return {};
            }
            return VocabularyRepository::instance().getWordsOnlyTextByVocabularyId(mistakes_book.id);
        }

        Vocabulary getDefaultVocabulary(int user_id)
        {
            try {
                return VocabularyRepository::instance().getDefaultVocabulary(user_id);
            }
            catch (const RepositoryExcept& e) {
                throw ServerExcept("Failed to get default vocabulary: " + std::string(e.what()));
            }
        }

        void setDefaultVocabulary(int user_id, int vocabulary_id)
        {
            try {
                VocabularyRepository::instance().setDefaultVocabulary(user_id, vocabulary_id);
            }
            catch (const RepositoryExcept& e) {
                throw ServerExcept("Failed to set default vocabulary: " + std::string(e.what()));
            }
        }

    private:
        VocabularyService() = default;
        VocabularyService(const VocabularyService &) = delete;
        VocabularyService &operator=(const VocabularyService &) = delete;
    };
}